/**
 * 资源加载监控
 */

import { ReportType } from './constant';
import { ReportParams } from './types';
import Utils from './utils';

export default class ResourcesError {
	reportedErrors = new Set<string>();
	observer: PerformanceObserver | null = null;

	constructor(private callback: (params: ReportParams) => void) {
		Utils.log('资源加载监控初始化成功');
		this.init();
	}
	init() {
		this.setupErrorEventListener();
		this.setupPerformanceObserver();
	}

	// 处理资源错误
	setupErrorEventListener() {
		window.addEventListener(
			'error',
			(event: any) => {
				// 只处理资源错误
				const sourceURL =
					event.target &&
					(event.target.src || event.target.href || event.target.currentSrc);
				if (sourceURL) {
					this.handleReport(sourceURL, 'error-event-listener');
				}
			},
			true
		);
	}

	/**
	 * 设置性能观察器捕获资源错误
	 */
	setupPerformanceObserver() {
		if (!window.PerformanceObserver) return;
		try {
			const errorObserver = new PerformanceObserver(list => {
				list.getEntries().forEach(entry => {
					if (entry.entryType === 'resource' && entry.duration === 0) {
						this.handleReport(entry.name, 'performance-observer');
					}
				});
			});

			errorObserver.observe({ type: 'resource' });
		} catch (e) {
			Utils.log('error', '资源错误观察器初始化失败', e);
		}
	}

	handleReport(sourceURL: string, subType: string) {
		if (this.reportedErrors.has(sourceURL)) return;
		this.reportedErrors.add(sourceURL);
		this.callback({
			type: ReportType.RESOURCES_ERROR,
			subType,
			message: '资源加载异常',
			selector: Utils.getSelectors(),
			sourceURL,
		});
	}
}
